#include "include/lc3.h"

LC3::LC3() { }

LC3::LC3(uint16_t x)
{
    *this = x;
}

/**
 * @brief : 
 *      取出指令中的某一比特位
 * @param : 
 *      uint16_t : 待读取的第 i 比特
 * @return : 
 *      uint16_t : 指令中返回该比特位对应的值
 */
uint16_t LC3::bit(uint16_t i)
{
    uint16_t x = group();
    return (x >> i) & 0x1;
} 

/**
 * @brief : 
 *      将指令中的各成分重组为 16bit 数返回
 * @return : 
 *      uint16_t : 组合的 16bit 指令
 */
uint16_t LC3::group()
{
    uint16_t inst16 = 0;
    inst16 |= (op << 12);
    inst16 |= (rd << 9) ;
    inst16 |= (rs << 6) ;
    inst16 |= (md << 5) ;
    inst16 |= (__ << 3) ;
    inst16 |= rt;
    return inst16;
}

/**
 * @brief : 
 *      从指令中分离出各组成成分，由参数中的引用来返回
 * @param : 
 *      uint16_t &op   : 传入指令操作码引用，同时作为返回值
 *      uint16_t &rd   : 传入指令的目的操作数寄存器引用，同时作为返回值
 *      uint16_t &rs   : 传入指令的第一操作数寄存器，同时作为返回值
 *      uint16_t &rt   : 传入指令的第二操作数寄存器，同时作为返回值
 */ 
 
void LC3::part (
    uint16_t& op_ref, 
    uint16_t& rd_ref, 
    uint16_t& rs_ref, 
    uint16_t& rt_ref
) {
    op_ref = this->op;
    rd_ref = this->rd;
    rs_ref = this->rs;
    rt_ref = this->rt;
}

/**
 * 功能:
 *      重载赋值运算符
 * @param : 
 *      uint16_t : 传入一个16位的数据
 */ 
 
void LC3::operator=(uint16_t x)
{
    this->op = x >> 12 ;
    this->rd = (x >> 9) & 0x7;
    this->rs = (x >> 6) & 0x7;
    this->md = (x >> 5) & 0x1;
    this->__ = (x >> 3) & 0x3;
    this->rt = x & 0x7;
}

/**
 * 功能:
 *      重载赋值运算符
 * @param : 
 *      LC3 : 传入一个 LC3 指令对象的引用
 */ 
 
void LC3::operator=(const LC3 &inst)
{
    this->op = inst.op;
    this->rd = inst.rd;
    this->rs = inst.rs;
    this->md = inst.md;
    this->__ = inst.__;
    this->rt = inst.rt;
}

/**
 * 功能:
 *      重载按位与运算符
 * @param : 
 *      uint16_t : 传入一个16位的数据
 */ 
 
uint16_t LC3::operator&(uint16_t x)
{
    uint16_t inst16 = group();
    return inst16 & x;
}

/**
 * 功能:
 *      重载左移运算符
 * @param : 
 *      uint16_t : 传入一个16位的数据
 */ 
 
uint16_t LC3::operator<<(uint16_t x)
{
    uint16_t inst16 = group();
    return inst16 << x;
}

/**
 * 功能:
 *      重载右移运算符
 * @param : 
 *      uint16_t : 传入一个16位的数据
 */ 
 
uint16_t LC3::operator>>(uint16_t x)
{
    uint16_t inst16 = group();
    return inst16 >> x;
}

